﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TFSTibcoDesignerRCSAdapter
{
    class Program
    {
        /// <summary>
        ///  The script will be called with 1 or 3 arguments. The first argument
        /// is the name of the command. If TIBCO Designer collected a comment, the
        /// the option '-comment' is passed along with a quoted string. Depending
        /// on the script or RCS system, that comment may or may not be usable.
        /// The name of the file to operate on is passed via stdin. Currently
        ///  rcs adapters only pass one file at a time.
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            var argsLength = args.Length;
            int MethodReturnValue = 0;
            if (argsLength==0)
            {
                LoggingMethods.Logerr("Error: No Args passed to TFSTibcoDesignerRCSAdapter. Try use it with one arg with value help to provide you intructions.");
                return;
            }
            else
            {
                //see if we have a comment flag, if we do extract the comment. 
                var commentIndex = args.ToList().IndexOf("-comment");
                string comment = "";
                if (commentIndex>0 && argsLength>commentIndex+1)
                {
                    comment = args[commentIndex + 1];
                }

                var command = args[0];
                if (command.Equals("isRevisionControlled"))
                {
                    RcsMethods.IsRevisionControlled(GetFileName(command));
                }
                else if (command.Equals("foldersRequireLockForParentWritability"))
                {
                    RcsMethods.FoldersRequireLockForParentWritability();
                }
                else if (command.Equals("supportsLocking"))
                {
                    RcsMethods.SupportsLocking();
                }
                else if (command.Equals("supportsCommit"))
                {
                    RcsMethods.SupportsCommit();
                }
                else if (command.Equals("info"))
                {
                    RcsMethods.Info(GetFileName(command));
                }
                else if (command.Equals("foldersRequireRecursiveLock"))
                {
                    RcsMethods.FoldersRequireRecursiveLock();
                }
                else if (command.Equals("supportsRecursiveLock"))
                {
                    RcsMethods.SupportsRecursiveLock();
                }
                else if (command.Equals("supportsSynchronize"))
                {
                    RcsMethods.SupportsSynchronize();
                }
                else if (command.Equals("wantsCommentOnAdd"))
                {
                    RcsMethods.WantsCommentOnAdd();
                }
                else if (command.Equals("revert"))
                {
                    MethodReturnValue = RcsMethods.Revert(GetFileName(command),false);
                }
                else if (command.Equals("revertRecursively"))
                {
                    MethodReturnValue = RcsMethods.Revert(GetFileName(command), true);
                }
                else if (command.Equals("specialVFileNames"))
                {
                    RcsMethods.SpecialVFileNames();
                }
                else if (command.Equals("add"))
                {
                    MethodReturnValue = RcsMethods.Add(GetFileName(command));
                }
                else if (command.Equals("commitPreview"))
                {
                    MethodReturnValue = RcsMethods.CommitPreview();
                }
                else if (command.Equals("commit"))
                {
                    MethodReturnValue = RcsMethods.Commit(comment);
                }
                else if (command.Equals("edit"))
                {
                    MethodReturnValue = RcsMethods.Edit(GetFileName(command), false);
                }
                else if (command.Equals("editRecursively"))
                {
                    MethodReturnValue = RcsMethods.Edit(GetFileName(command), true);
                }
                else if (command.Equals("delete"))
                {
                    MethodReturnValue = RcsMethods.Delete(GetFileName(command));
                }
                else if (command.Equals("updatePreview"))
                {
                    MethodReturnValue = RcsMethods.UpdatePreview();
                }
                else if (command.Equals("update"))
                {
                    MethodReturnValue = RcsMethods.Update();
                }
                else if (command.Equals("encrypt"))
                {
                    if (args.Length >= 2)
                    {
                        var stext = args[1];
                        Console.Out.WriteLine(String.Format("Your encrypted string is the following: {0}", RcsMethods.Encrypt(stext)));
                    }
                    else
                    {
                        Console.Out.WriteLine("Second Argument for text to encrypt is not provided!");
                    }
                    
                }
                else if (command.Equals("decrypt"))
                {
                    if (args.Length >= 2)
                    {
                        var stext = args[1];
                        Console.Out.WriteLine(String.Format("Your decrypted string is the following: {0}", RcsMethods.Decrypt(stext)));
                    }
                    else
                    {
                        Console.Out.WriteLine("Second Argument for text to decrypt is not provided!");
                    }
                }

                else if (command.Equals("help"))
                {
                    Console.Out.WriteLine("This is the help for TFSTibcoDesignerRCSAdapter.\r\n");
                    Help();
                }
                else
                {
                    LoggingMethods.Debug(string.Format("Error: Unknown command {0}", command));
                    return;
                }
                LoggingMethods.Debug(string.Format("Command: {0} have been called.", command));
                Environment.Exit(MethodReturnValue);
            }
            


        }
        static void Help()
        {
            Console.Out.WriteLine("The syntax for the tool is the following:\r\n");
            Console.Out.WriteLine("TFSTibcoDesignerRCSAdapter \"command\" | -comment 'some text' | \"second_arg\"\r\n");
            Console.Out.WriteLine("where \"command\" may be any of the following:");
            Console.Out.WriteLine("=>Commands without any input which are used for configuration of RCS adapter:");
            Console.Out.WriteLine("supportsLocking, supportsCommit, foldersRequireRecursiveLock, supportsRecursiveLock, supportsSynchronize, wantsCommentOnAdd, specialVFileNames\r\n");
            Console.Out.WriteLine("=>Commands with one input which is the filepath of item ti be checked for tfs (and this is the next input passed by user):");
            Console.Out.WriteLine("isRevisionControlled, revert, revertRecursively, edit, editRecursively, delete, add, info\r\n");
            Console.Out.WriteLine("=>Commands without any input nad used by RCS adapter for the whole project path:");
            Console.Out.WriteLine("commitPreview, commit, updatePreview, update\r\n");
            Console.Out.WriteLine("=>And commands which takes as input a second argument:");
            Console.Out.WriteLine("encrypt, decrypt\r\n\r\n");
            Console.Out.WriteLine("Optionally user may provide the option \"-comment 'sometext' \" where the 'sometext' value inserted as comment into the \"add\" and \"commit\" commands.");
            Console.Out.WriteLine("Especially for commit if your comments is with the format:##xyz## where xyz is the TFS task number, then the changeset for the checkin commands is associated with the task by number xyz.\r\n\r\n");
            Console.Out.WriteLine("Optionally \"second_arg\" argument is used for commands:encrypt, decrypt and is the text we want to encrypt or decrypt.\r\n");
            Console.Out.WriteLine("Application Configuration File values description\r\n");
            Console.Out.WriteLine("==>SupportsCheckIns  : Gets value true if we want RCS adapter to be able to perform check ins(commits)\r\n");
            Console.Out.WriteLine("==>TeamFSURL         : The Url for Team Foundation Server eg. http://myteamfsserver:8080/\r\n");
            Console.Out.WriteLine("==>NeedsCommentsOnAdd: Set the value as true if you want RCS adapter to ask you provide comments on add command\r\n");
            Console.Out.WriteLine("==>LogFileSize       : The file size (in bytes) of log file before its been rollover eg. 5120000000\r\n");
            Console.Out.WriteLine("==>ByPassCheckIsRevisionControl: Set to true if you want to bypasss the command isRevisionControlled. Do this if your project contains many files and this operation delays\r\n");
            Console.Out.WriteLine("==>TeamFSUsername    : Set the value here for TFS connectivity if your pc is not joined in the domain or have different authentication.\r\n");
            Console.Out.WriteLine("==>TeamFSPassword    : Set the value here for TFS connectivity if your pc is not joined in the domain or have different authentication.\r\n");
            Console.Out.WriteLine("==>TeamFSDomain      : Set the value here for TFS connectivity if your pc is not joined in the domain or have different authentication.\r\n");
            Console.Out.WriteLine("==>LogInFile         : Set the value to true if you want to log oprations in the debug file.\r\n");
            Console.Out.WriteLine("==>LogFileLocation   : The folder to create and write to the Log file.\r\n");
        }
        /// <summary>
        /// returns the filename passed via stdin or nil if none. Logs the file got if the
        /// relevant configuration variable is enabled.
        /// </summary><returns></returns>
        static string GetFileName(string command)
        {
            string sfileName = "";
            try
            {
                sfileName = Console.ReadLine();
                if (sfileName.StartsWith("imp:///"))
                    sfileName = sfileName.Substring(sfileName.IndexOf("imp:///")+7);
            }
            catch (Exception exc)
            {
                LoggingMethods.Logerr(exc.InnerException.ToString());
            }
            LoggingMethods.Debug(String.Format("Action GetFileName for command {0} returned:{1}", command, sfileName??""));

            return sfileName;
        }
    }
}
